//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
#ifndef __BOOT_KEYPAD_H
#define __BOOT_KEYPAD_H

#include <bootDevice.h>

#ifdef __cplusplus
extern "C" {
#endif

//-------------------------------------------------------------------------------------------------------------------
//
// Important Note: The following mappings are expected to exist by Boot Terminal
//
// VT_TACTION must be mapped to the Action key.
// VK_TBACK must be mapped to the Back key for backspace feature.
// VK_TSTAR must be mapped to a key for interactive change input mode feature.
// VK_THOME must be mapped to a key on the keypad for interactive show/hide status bar feature.
//
//-------------------------------------------------------------------------------------------------------------------
//
// Aliases
//
#define BOOT_KEYPAD_INIT            BOOT_DEVICE_INIT

//------------------------------------------------------------------------------

enum BOOT_KEYPAD_IOCTL {
    BOOT_KEYPAD_IOCTL_ISPRESSED = 0x00030001,
    BOOT_KEYPAD_IOCTL_SCAN4KEYS = 0x00030002,
    BOOT_KEYPAD_IOCTL_GETPROPS  = 0x00030003,
};

typedef struct BOOT_KEYPAD_SCAN4KEYS_PARAMS {
    UINT16* pVkeyList;              // array of virtual key codes to scan for being pressed
    UINT16  vkeyListSz;             // number of vkeys in array 
    UINT16* pVkey;                  // vkey of first pressed key in the list or -1 if no match    
} BOOT_KEYPAD_SCAN4KEYS_PARAMS;

#define VK_NONE  0xffff             // no key press detected

//------------------------------------------------------------------------------
//  Define VK typically used on WM

#ifndef _WINUSERM_H_

#define VK_THOME                0x5B
#define VK_TBACK                0x1B
#define VK_TSOFT1               0x70
#define VK_TSOFT2               0x71
#define VK_TUP                  0x26

#define VK_T1                   L'1'
#define VK_T2                   L'2'
#define VK_T3                   L'3'
#define VK_TTALK                0x72
#define VK_TRIGHT               0x27

#define VK_T4                   L'4'
#define VK_T5                   L'5'
#define VK_T6                   L'6'
#define VK_TEND                 0x73
#define VK_TLEFT                0x25

#define VK_T7                   L'7'
#define VK_T8                   L'8'
#define VK_T9                   L'9'
#define VK_TVOLUMEDOWN          0x76
#define VK_TDOWN                0x28

#define VK_TSTAR                0x77
#define VK_T0                   L'0'
#define VK_TPOUND               0x78
#define VK_TVOLUMEUP            0x75
#define VK_TACTION              0x0D

#define VK_TPOWER               0x81
#define VK_TFLIP                0x80
#define VK_TRECORD              0x79

#endif

//------------------------------------------------------------------------------

#ifndef dimof
#define dimof(x)                    (sizeof(x)/sizeof(x[0]))
#endif

//------------------------------------------------------------------------------
//
//  Function: BootKeypadInit
//
//  This is proxy for BOOT_DEVICE_PFN_INIT function.
//
__inline
HANDLE
BootKeypadInit(
    BOOT_DEVICE_INIT* pInit
    )
{
    BOOT_DEVICE_IFC* pIfc = NULL;
    
    if (!pInit->pfnInit(pInit->pContext, pInit->contextSize, &pIfc))
        {
        pIfc = NULL;
        }
    return pIfc;
}

//------------------------------------------------------------------------------
//
//  Function:  BootKeypadDeinit
//
__inline
BOOL
BootKeypadDeinit(
    HANDLE hKeypad
    )
{
    BOOT_DEVICE_IFC *pIfc = (BOOT_DEVICE_IFC*)hKeypad;
    return pIfc->pfnDeinit(pIfc->hDevice);
}

//------------------------------------------------------------------------------

__inline
BOOL
BootKeypadIsPressed(
    HANDLE hKeypad,
    UINT16 vkey
    )
{
    BOOT_DEVICE_IFC *pIfc = (BOOT_DEVICE_IFC*)hKeypad;
    return pIfc->pfnIoCtl(
        pIfc->hDevice, BOOT_KEYPAD_IOCTL_ISPRESSED, &vkey, sizeof(vkey)
        );
}

//------------------------------------------------------------------------------

__inline
BOOL
BootKeypadScanForKeys(
    HANDLE hKeypad,
    UINT16* pVkeyList,      // array of virtual key codes to scan for being pressed
    UINT16  vkeyListSz,     // dim of array 
    UINT16* pVkey           // vkey of first pressed key in the list or -1 if no match
    )
{
    BOOT_DEVICE_IFC *pIfc = (BOOT_DEVICE_IFC*)hKeypad;
    BOOT_KEYPAD_SCAN4KEYS_PARAMS params;
    
    params.pVkeyList  = pVkeyList;
    params.vkeyListSz = vkeyListSz;
    params.pVkey      = pVkey;

    return pIfc->pfnIoCtl(
        pIfc->hDevice, BOOT_KEYPAD_IOCTL_SCAN4KEYS, &params, sizeof(params)
        );
}

//------------------------------------------------------------------------------

__inline
BOOL
BootKeypadGetProps(
    HANDLE hKeypad,
    DWORD* pMinKeyCheckTime
    )
{
    BOOT_DEVICE_IFC *pIfc = (BOOT_DEVICE_IFC*)hKeypad;
    return pIfc->pfnIoCtl(
        pIfc->hDevice, BOOT_KEYPAD_IOCTL_GETPROPS, pMinKeyCheckTime, sizeof(pMinKeyCheckTime)
        );
}

//------------------------------------------------------------------------------

#ifdef __cplusplus
}
#endif

#endif // __BOOT_KEYPAD_H
